package edu.pku.sei.transformation.atl.adapter;

import java.util.ArrayList;
import java.util.List;

import edu.pku.sei.modeler.model.core.MetaNamedElement;
import edu.pku.sei.transformation.atl.rule.IATLExpression;
import edu.pku.sei.transformation.atl.rule.IATLLink;
import edu.pku.sei.transformation.atl.rule.IATLNode;
import edu.pku.sei.transformation.atl.rule.IATLType;
import edu.pku.sei.transformation.editor.model.Expression;
import edu.pku.sei.transformation.editor.model.variable.ObjectVariable;

/**
 * represent a object in pattern
 * 
 * @author FengChao
 * 
 */
public class ATLNodeAdapter implements IATLNode {
	boolean undefine = true;
	ArrayList<IATLLink> outlinks = new ArrayList<IATLLink>();
	ArrayList<IATLExpression> exps = new ArrayList<IATLExpression>();
	ObjectVariable node = null;
	ATLInvokeExpression createRule = null;

	public ATLNodeAdapter(ObjectVariable node) {
		this.node = node;
		for (Object obj : node.getExpressions()) {
			if (obj instanceof Expression) {
				exps.add(new ATLExpressionAdapter((Expression) obj, node,
						ExpressionPosition.node));
			}
		}
	}

	@Override
	public List<IATLLink> getLinks() {
		return outlinks;
	}

	@Override
	public String getName() {
		return node.getName();
	}

	@Override
	public IATLType getType() {
		return new ATLModelTypeAdapter((MetaNamedElement) node.getType());
	}

	@Override
	public List<IATLExpression> getExps() {
		return exps;
	}

	/**
	 * convert this object to string first time visit, output declaration(name,
	 * type and attributes initialization) of the object then, output
	 * reference(name) of the object
	 */
	public String toString() {
		if (undefine) {
			String s = "";
			// if the object if create by other rule, invoke this rule
			if (createRule != null) {
				s = createRule.getContent();
			}
			// else initialize this object
			else {
				s += getName();
				s += " : ";
				s += getType().getName();
				s += "(";
				// add associate
				for (IATLLink link : getLinks()) {
					s += link.getName() + "=" + link.getTarget().toString()
							+ ",";
				}
				// remove last ","
				if (s.charAt(s.length() - 1) == ',')
					s = s.substring(0, s.length() - 1);
				// add expression
				for (IATLExpression expression : getExps()) {
					s += expression.getContent() + ",";
				}
				// remove last ","
				if (s.charAt(s.length() - 1) == ',')
					s = s.substring(0, s.length() - 1);
				s += ")";
			}
			undefine = false;
			return s;

		} else {
			return this.getName();
		}
	}

}
